﻿namespace ScrumFactory.Data.Sql {
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Data.Objects;
    using System.Data.EntityClient;
    using System.Transactions;
    using System.Linq;

    [Export(typeof(ITeamRepository))]
    public class SqlTeamRepository : ITeamRepository {
        private string connectionString;

        [ImportingConstructor()]
        public SqlTeamRepository(
            [Import("ScrumFactoryEntitiesConnectionString")]
            string connectionString) {
            this.connectionString = connectionString;
        }

        public ICollection<ScrumFactory.MemberProfile> GetAllMembers() {
            using (var context = new ScrumFactoryEntities(this.connectionString)) {

                var members = from m in context.MembersProfile
                              select new {
                                  MemberProfile = m,
                                  Memberships =
                                      from ms in context.ProjectMemberships                                      
                                      where ms.DayAllocation > 0
                                      select new { ms }
                              };
                return members.AsEnumerable().Select(m => m.MemberProfile).ToList<MemberProfile>();
                  
            }
        }


        public MemberProfile GetMember(string memberUId) {
            using (var context = new ScrumFactoryEntities(this.connectionString)) {

                var member =
                        from m in context.MembersProfile
                        where m.MemberUId==memberUId
                        select new { MemberProfile = m, Memberships = m.Memberships.Where(ms => ms.DayAllocation>0) };
                
                if (member == null)
                    return null;

                return member.AsEnumerable().Select(m => m.MemberProfile).ToList<MemberProfile>()[0];
            }
        }

        /// <summary>
        /// Gets the project members for a given project.
        /// The Memberships collection of each member is also filled
        /// with the corresponding role(s) of the member at the project.
        /// </summary>
        /// <param name="projectUId">The project Uid.</param>
        /// <returns>The project members</returns>
        public ICollection<MemberProfile> GetProjectMembers(string projectUId) {
            using (var context = new ScrumFactoryEntities(this.connectionString)) {

                var projectMembers =
                        from m in context.MembersProfile
                        where m.Memberships.Where(ms => ms.ProjectUId == projectUId).Any()
                        select new { MemberProfile = m, Memberships = m.Memberships.Where(ms => ms.ProjectUId == projectUId) };

                return projectMembers.AsEnumerable().Select(m => m.MemberProfile).ToList<MemberProfile>();
            }
        }

        public void SaveProjectMembership(ProjectMembership membership) {
            using (var context = new ScrumFactoryEntities(this.connectionString)) {
                ProjectMembership existMembership = context.ProjectMemberships.SingleOrDefault(m => m.MemberUId == membership.MemberUId && m.ProjectUId == membership.ProjectUId && m.RoleUId == membership.RoleUId);
                if (existMembership == null) {
                    context.ProjectMemberships.AddObject(membership);
                } else {
                    context.AttachTo("ProjectMemberships", existMembership);
                    context.ApplyCurrentValues<ProjectMembership>("ProjectMemberships", membership);
                }
                context.SaveChanges();
            }
        }

        

        public void DeleteProjectMembership(ProjectMembership membership) {
            using (var context = new ScrumFactoryEntities(this.connectionString)) {
                ProjectMembership existMembership = context.ProjectMemberships.SingleOrDefault(m => m.MemberUId == membership.MemberUId && m.ProjectUId == membership.ProjectUId && m.RoleUId == membership.RoleUId);
                if (existMembership == null)
                    return;
                context.ProjectMemberships.DeleteObject(existMembership);
                context.SaveChanges();
            }
        }

    }
}
